<?php
/**
 * Redis操作
 */
namespace Common\Org;

class PhpRedis
{
    protected $redis = null;
    protected static $singleton_redis = null;
    protected $keys = array();
    private $exceptionCode = array();

    public function __construct($dbindex=false){
        $this->keys = C('REDIS_KEYS');
        $this->exceptionCode = C('EXCEPTION_CODE');
        if (!self::$singleton_redis) {
            self::$singleton_redis = new \Redis();
            self::$singleton_redis->connect(C('REDIS_HOST'), C('REDIS_PORT'), 0 );
            $this->redis = self::$singleton_redis;
        } else {
            $this->redis = self::$singleton_redis;
        }
        $this->select($dbindex ? $dbindex : 0);

    }

    protected function checkKey($key)
    {
        return ;
        $keyArr = explode(':SpecVar:',$key);
        if (count($keyArr)>1){
            $key=$keyArr[0].':SpecVar:';//实现只检查:SpecVar:之前的KEY部分
        } else {
            $key = $keyArr[0];
        }
        if (!array_key_exists($key, $this->keys) || !$this->keys[$key]) {
            throw new \Exception($this->exceptionCode['130010'].'['.$key.']',130010);
        }
    }

    public function ping()
    {
       return $this->redis->ping();
    }

    public function select($num){
        return $this->redis->select($num);
    }

    public function set($key,$vale,$expire=false){
        $this->checkKey($key);
        $ok = $this->redis->set($key,$vale);
        if($expire){
            $this->redis->expire($key,$expire);
        }
        return $ok;
    }

    public function get($key){
        $this->checkKey($key);
        return $this->redis->get($key);
    }

    public function del($key){
        $this->checkKey($key);
        return $this->redis->del($key);
    }

    public function getRedis(){
        return $this->redis;
    }

    public function lock($key){
        $this->checkKey($key);
        return $this->redis->setNx($key,1)?true:false;
    }
    public function lock_wait($key,$times=5){
        $this->checkKey($key);
        $r = $this->lock($key);
        if(!$r){
            for ($i=0; $i <$times ; $i++) {
                usleep(rand(500,1000));
                $r = $this->lock($key);
                if($r)
                   break;
               $i++;
            }
        }
        return $r;
    }

    public function unlock($key){
        $this->checkKey($key);
        $this->redis->del($key);
    }

    public function incr($key){
        $this->checkKey($key);
        $this->redis->incr($key);
    }

    public function lLen($key)
    {
        $this->checkKey($key);
        return $this->redis->lLen($key);
    }

    public function lPush($key,$value)
    {
        $this->checkKey($key);
        return $this->redis->lPush($key,$value);
    }

    public function lPop($key)
    {
        $this->checkKey($key);
        return $this->redis->lPop($key);
    }

    public function rPush($key,$value)
    {
        $this->checkKey($key);
        return $this->redis->rPush($key,$value);
    }

    public function rPop($key)
    {
        $this->checkKey($key);
        return $this->redis->rPop($key);
    }

    public function lRange($key, $start=0, $stop=0)
    {
        $this->checkKey($key);
        return $this->redis->lRange($key, $start, $stop);
    }

    public function exists($key)
    {
        $this->checkKey($key);
        return $this->redis->exists($key);
    }


    public function publish($key,$value){
        $this->checkKey($key);
        return $this->redis->publish($key,$value);
    }

    //取出有序集合中的元素
    public function zrange($key,$star,$end,$withscores=false){
        $this->checkKey($key);
        return $this->redis->zRange($key,$star,$end,$withscores?'withscores':'');
    }

    //移除集合中的一个或多个成员
    public function srem($key,$value){
        return $this->redis->srem($key,$value);
    }

    //移除有序集合一个或多个成员
    public function zrem($key,$member){
        $this->checkKey($key);
        return $this->redis->zrem($key,$member);
    }

    //添加集合
    public function sadd($key,$value){
        $this->checkKey($key);
        return $this->redis->sadd($key,$value);
    }

    //添加有序集合
    public function zadd($key,$score,$member){
        $this->checkKey($key);
        return $this->redis->zadd($key,$score,$member);
    }

    //获取匹配的key
    public function scan($it,$pattern='',$count=10){
        return $this->redis->scan($it,$pattern,$count);
    }

    /*
    删除一个或hash字段
    @param $hashkey
    @param $fields array(key1,key2...)
    */
    public function hDel($hashkey,$fields){
        $this->checkKey($hashkey);
        if (!is_array($fields)){
            $fields = array($fields);
        }
        foreach ($fields as $key) {
                $this->redis->hDel($hashkey,$key);
        }
        $len = $this->hLen($hashkey);
        if ($len<1)
            $this->del($hashkey);
    }
    /*
        名称为$hashkey的hash中是否存在，名称为$key的健
        @param $hashkey
        @param $key
        @return bool
    */
    public function hExists($hashkey,$key)
    {
        $this->checkKey($hashkey);
        return $this->redis->hExists($hashkey,$key);
    }

    /*
        向名称为hashkey的hash中添加元素key—>$val
    */
    public function hSet($hashkey,$key,$val)
    {
        $this->checkKey($hashkey);
        return $this->redis->hSet($hashkey,$key,$val);
    }

    /*
        从hashkey的hash中读取key的值内容
    */
    public function hGet($hashkey,$key)
    {
        $this->checkKey($hashkey);
        return $this->redis->hGet($hashkey,$key);
    }

    //获得hash内字段的数量
    public function hLen($hashkey)
    {
        $this->checkKey($hashkey);
        return $this->redis->hLen($hashkey);
    }


}